package no.saiboten.milkywave.controller;

import java.util.List;
import java.util.UUID;
import java.util.logging.Logger;

import no.saiboten.milkywave.component.WaterLevelEntity;
import no.saiboten.milkywave.entity.MailContent;
import no.saiboten.milkywave.entity.User;
import no.saiboten.milkywave.mail.MailSender;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

@Controller
public class AdminController {

	private static final Logger LOGGER = Logger.getLogger(AdminController.class
			.getName());

	Objectify ofy;

	WaterLevelEntity waterLevel;

	private MailSender mailSender;

	@Autowired
	public AdminController(WaterLevelEntity waterLevel, MailSender mailSender) {
		this.waterLevel = waterLevel;
		this.mailSender = mailSender;

		ObjectifyService.register(User.class);
		ObjectifyService.register(MailContent.class);

		ofy = ObjectifyService.begin();
	}

	@RequestMapping(value = "/admin/overview", method = RequestMethod.GET)
	public ModelAndView adminOverview(
			@RequestParam(value = "feedback", required = false) String feedback) {
		ModelAndView mav = getDefaultModelAndView();
		String result = null;
		if (feedback != null) {
			result = findFeedback(feedback);
		}

		mav.addObject("result", result);

		return mav;
	}

	@RequestMapping(value = "/admin/user/{mail}", method = RequestMethod.GET)
	public ModelAndView seeUser(@PathVariable(value = "mail") String mail) {
		User user = ofy.get(User.class, mail);
		ModelAndView mav = new ModelAndView("user");
		mav.addObject("user", user);
		return mav;
	}

	@RequestMapping(value = "/admin/sendMail", method = RequestMethod.POST)
	public RedirectView sendMail(@RequestParam String subject,
			@RequestParam String content) {

		mailSender.sendMailToAllMembers(subject, content);
		RedirectView mav = new RedirectView("/admin/overview?feedback=mailsent");
		return mav;
	}

	@RequestMapping(value = "/admin/addUser", method = RequestMethod.POST)
	public RedirectView addUserPost(
			@RequestParam("mail") String mailStr,
			@RequestParam(required = false, value = "firstName") String firstName,
			@RequestParam(required = false, value = "lastName") String lastName,
			@RequestParam(required = false, value = "phoneNumber") String phoneNumber) {
		LOGGER.info("Adding mail: " + mailStr);

		User mail = new User();
		mail.setMail(mailStr);
		mail.setFirstName(firstName);
		mail.setLastName(lastName);
		mail.setPhoneNumber(phoneNumber);
		mail.setDeletionCode(UUID.randomUUID().toString());
		mail.setConfirmed(true);

		ofy.put(mail);

		RedirectView mav = new RedirectView(
				"/admin/overview?feedback=useradded");
		return mav;
	}

	@RequestMapping(value = "/admin/deleteUser", method = RequestMethod.GET)
	public RedirectView deleteUser(@RequestParam("mail") String uuid) {
		LOGGER.info("Deleting mail: " + uuid);
		User mail = new User();
		mail.setDeletionCode(uuid);
		ofy.delete(mail);

		RedirectView mav = new RedirectView(
				"/admin/overview?feedback=userdeleted");
		return mav;
	}

	@RequestMapping(value = "/admin/adjustRequiredWaterLevel", method = RequestMethod.POST)
	public RedirectView addMailGet(@RequestParam("waterLevel") Integer newValue) {
		LOGGER.info("Adjusting waterlevel to: " + newValue);
		waterLevel.setWaterLevel(newValue);
		RedirectView mav = new RedirectView(
				"/admin/overview?feedback=waterleveladjusted");
		return mav;
	}

	@RequestMapping(value = "/admin/changeContent", method = RequestMethod.POST)
	public RedirectView changeMailContent(
			@RequestParam("subject") String subject,
			@RequestParam("content") String content) {
		LOGGER.info("Setting content to: " + content);

		MailContent mailContent = new MailContent();
		mailContent.setContent(content);
		mailContent.setSubject(subject);
		mailContent.setId(1);

		ofy.put(mailContent);

		RedirectView mav = new RedirectView(
				"/admin/overview?feedback=contentchange");
		return mav;
	}

	@RequestMapping(value = "/admin/activatemail", method = RequestMethod.GET)
	public RedirectView activateOrDeactivateMail(
			@RequestParam("activate") Boolean activated) {
		LOGGER.info("Adjusting waterlevel to: " + activated);
		mailSender.setActivated(activated);
		RedirectView mav = null;

		if (mailSender.isActivated()) {
			mav = new RedirectView("/admin/overview?feedback=mailactivated");
		} else {
			mav = new RedirectView("/admin/overview?feedback=maildeactivated");
		}
		return mav;
	}

	private String findFeedback(String feedback) {
		if (feedback.equals("mailsent")) {
			return "Mail sent til alle medlemmer!";
		} else if (feedback.equals("waterleveladjusted")) {
			return "Vannivå justert!";
		} else if (feedback.equals("useradded")) {
			return "Bruker lagt til";
		} else if (feedback.equals("userdeleted")) {
			return "Bruker slettet";
		} else if (feedback.equals("mailactivated")) {
			return "Mailsending er aktivert";
		} else if (feedback.equals("maildeactivated")) {
			return "Mailsending er deaktivert";
		} else if (feedback.equals("contentchange")) {
			return "Endret innhold!";
		}
		return "";
	}

	private ModelAndView getDefaultModelAndView() {
		ModelAndView mav = new ModelAndView("admin");

		Query<User> mails = ofy.query(User.class);
		mav.addObject("mails", mails.list());
		mav.addObject("waterlevel", waterLevel.getWaterLevel());
		mav.addObject("mailActivated", mailSender.isActivated());

		List<MailContent> mailContentList = ofy.query(MailContent.class).list();
		if (mailContentList.size() > 0) {
			MailContent content = ofy.get(MailContent.class, 1);
			mav.addObject("content", content.getContent());
			mav.addObject("subject", content.getSubject());
		}

		return mav;
	}
}
